<?php
/**
 * 百度Echarts插件Widget
 */

namespace common\widgets;


use yii;
use yii\helpers\Html;
use common\assets\EchartsAsset;

class Echarts extends Widget {

    /*
     * 类型
     * Sample: line, pie, map, bar, tree ...
     */
    public $type;

    public $legend;
    public $x;
    public $y;
    public $data;
    public $title;
    public $subtext = '';


    public $tooltip;

    public $series;


    /*
     * 内部JS模板
     */
    protected $template;

    protected $js;


    public function init(){
        parent::init();
        if(empty($this->title))
            $this->title = '图表';
        EchartsAsset::register($this->getView());
        $this->js = 'var myChart_'.$this->options['id'].' = echarts.init(document.getElementById(\''.$this->options['id'].'\'), \'macarons\');';
        if($this->type == 'line'){
            $this->initTitle();
            $this->initTooltip(['trigger'=>'axis']);
            $this->initToolbox();
            $this->initLegend();
            $this->initXAxis();
            $this->initYAxis();
            $this->buildLineData();
            $this->initSeries();
        }elseif($this->type == 'bar'){
            $this->initTitle();
            $this->initTooltip(['trigger'=>'axis']);
            $this->initToolbox();
            $this->initLegend();
            $this->initXAxis();
            $this->initYAxis();
            $this->buildBarData();
            $this->initSeries();
        }elseif($this->type == 'tree'){
            $this->initTitle();
            $this->initTooltip(['trigger'=>'axis']);
            $this->initToolbox();
            $this->buildTreeData();
            $this->initSeries();
        }elseif($this->type == 'pie'){
            $this->initTitle();
            $this->initTooltip(['trigger'=>'axis']);
            $this->initToolbox();
            $this->buildPieData();
            $this->initSeries();
        }elseif($this->type == 'map'){
            $this->initTitle();
            $this->initTooltip(['trigger'=>'item']);
            $this->initToolbox();
            $this->buildMapData();
            $this->initSeries();
        }
    }

    public function run(){
        if(!isset($this->options['width']))
            $this->options['width'] = '100%';
        if(!isset($this->options['height']))
            $this->options['height'] = '360px';
        echo Html::tag('div', '', ['id'=>$this->options['id'], 'style'=>'width:'.$this->options['width'].';height:'.$this->options['height'].';']);

        $this->js =  $this->js . $this->options['id']."_option = {
            " . trim(implode(',', $this->template), ','). "
            }
            myChart_".$this->options['id'].".setOption(".$this->options['id']."_option);";
        $view = $this->getView();
        $view->registerJs($this->js);
    }

    /*
     * 将数组转换成字符串
     */
    private function arrToStr($array, $glue = ',', $quot = "'"){
        $output = '';
        if(!empty($array) && is_array($array)){
            foreach($array as $k => $v){
                if(is_string($v)){
                    $output .= $quot . $v . $quot . $glue;
                }elseif(is_numeric($v)){
                    $output .= $v . $glue;
                }
            }
            $output = trim($output, $glue);
        }
        return $output;
    }

    /*
     * 将数组转换成JSON字符串
     * 这个和json_encode 的区别在：1.于键值不加单引号；2.只转换一层，不会递归转换，如果碰到值为数组，则调用arrToStr方法
     */
    private function arrToJson($array){
        $output = [];
        if(!empty($array) && is_array($array)){
            foreach($array as $k => $v){
                if(is_numeric($v)){
                    $output[] = $k . ':' . $v;
                }elseif(is_string($v)){
                    //如果检测到是转换好的JSON结构，则不加引号了
                    if(preg_match('/^\{.*\}$/i', $v)){
                        $output[] = $k . ':' . $v;
                    }else{
                        $output[] = $k . ':' . "'" . $v . "'";
                    }

                }elseif(is_bool($v)){
                    if($v){
                        $output[] = $k . ':true';
                    }else{
                        $output[] = $k . ':false';
                    }
                }elseif(is_null($v)){
                    $output[] = $k . ':null';
                }elseif(is_array($v)){
                    $output[] = $this->arrToStr($v);
                }
            }
            return '{' . implode(',', $output) . '}';
        }else{
            return '';
        }
    }


    /**********************************************初始化模板************************************************************/

    /*
     * 初始化标题模板
     */
    protected function initTitle(){
        if(!empty($this->title)){
            if(is_array($this->title)){
                if(!isset($this->title[1])) $this->title[1] = '';
                $this->title = [
                    'text' => $this->title[0],
                    'subtext' => $this->title[1],
                ];
            }else{
                $this->title = [
                    'text' => $this->title,
                    'subtext' => $this->subtext,
                ];
            }
            $this->template['title'] = " title : ".$this->arrToJson($this->title);
        }
    }

    /*
     * 初始化提示模板
     * @param array $options 配置数组
     */
    protected function initTooltip($options = []){
        $this->template['tooltip'] = '
        tooltip : '.$this->arrToJson($options);
    }

    /*
     * 初始化工具模板
     */
    protected function initToolbox(){
        $feature = [];
        if($this->type == 'line'){
            $feature = [
                'magicType' => "{show: true, type: ['line', 'bar']}"
            ];

        }elseif($this->type == 'pie'){
            $feature = [
                'magicType' => "{show: true, type: ['pie', 'funnel'], option:{funnel:{x:'25%',width:'25%',funnelAlign:'left'}}}",
                'dataView' => "{show: true, readOnly: false}",
            ];

        }
        $feature['saveAsImage'] = ['show' => true];
        $this->template['toolbox'] = "
                toolbox: {
                    show : true,
                    feature : " . $this->arrToJson($feature) . "
                }";
    }

    /*
     * 初始化Legend模板
     */
    protected function initLegend(){
        $this->template['legend'] = "
                legend: {
                    data:[__legend__]
                }";
        if(empty($this->legend)){
            unset($this->template['legend']);
        }else{
            $this->legend = $this->arrToStr($this->legend);
            $this->template['legend'] = str_replace('__legend__', $this->legend, $this->template['legend']);
        }
    }

    /*
     * 初始化坐标模板
     */
    protected function initXAxis(){
        $this->template['xAxis'] = "
                xAxis : [
                    {
                        type : 'category',
                        boundaryGap : false,
                        data : [__x__]
                    }
                ]";

        if(empty($this->x)){
            $a = array();
            foreach($this->data as $k => $v){
                $a[] = $k;
            }
            $this->x = $a;
        }
        $this->template['xAxis'] = str_replace('__x__', $this->arrToStr($this->x), $this->template['xAxis']);
    }

    /*
     * 初始化纵坐标模板
     */
    protected function initYAxis(){
        $this->template['yAxis'] = "
                yAxis : [
                    {
                        type : 'value'
                    }
                ]
        ";
    }

    /*
     * 初始化Series模板
     */
    protected function initSeries(){
        $this->template['series'] = "
            series : [
                    __data__
                ]
        ";
        $this->template['series'] = str_replace('__data__', $this->data, $this->template['series']);
    }


    /******************************** 根据Echarts类型[type]构建不同的数据 *************************************************/

    /*
     * 组成 线形图 数据
     */
    protected function buildLineData(){
        $output = '';
        if(!empty($this->data) && is_array($this->data)){
            foreach($this->data as $group => $data){
                $output .= "{
                    name : '$group',
                    type : 'line',
                    stack: '总量',
                    areaStyle: {normal: {}},
                    data : [". $this->arrToStr($data) ."]
                },";
            }
        }
        $this->data = trim($output, ',');
    }

    /*
     * 组成 柱状图 数据
     */
    protected function buildBarData(){
        $output = '';
        if(!empty($this->data) && is_array($this->data)){
            foreach($this->data as $group => $data){
                $output .= "{
                    name : '$group',
                    type : 'bar',
                    data : [". $this->arrToStr($data) ."]
                },";
            }
        }
        $this->data = trim($output, ',');
    }

    /*
     * 饼状图数据
     */
    protected function buildPieData(){

        $this->template['tooltip'] = "
                 tooltip : {
                    trigger: 'item',
                    formatter: \"{b} : {c} ({d}%)\"
                }";

        $output = '';
        $data_str = array();
        if(!empty($this->data) && is_array($this->data)){
            foreach($this->data as $k => $v){
                $data_str[] = "{value:$v, name:'$k'}";
            }
        }
        $data_str = trim(implode($data_str, ','), ',');
        $title = serialize($this->title);
        $output .= "{
                    name : '$title',
                    type : 'pie',
                    radius : '55%',
                    center: ['50%', '60%'],
                    data : [".$data_str."]
                },";
        $this->data = $output;
    }


    /*
     * 构建 地图 数据
     */
    protected function buildMapData(){
        $data = [];
        var_dump($this->data);
        foreach($this->data as $k => $v){
            $data[] = ['name'=>$k, 'value'=>$v];
        }
        var_dump($data);
        $this->data = $this->arrToJson($data);
        var_dump($this->data); die;
    }

    /*
     * 构建 树状图 数据
     */
    protected function buildTreeData(){
        $template = "{
            name:'树图',
            type:'tree',
            orient: 'horizontal',
            rootLocation: {x: 100,y: 230},
            nodePadding: 32,
            layerPadding: 200,
            hoverable: true,
            roam: true,
            symbolSize: 6,
            itemStyle: {
                normal: {
                    color: '#4883b4',
                    label: {
                        show: true,
                        position: 'top',
                        formatter: \"{b}\",
                        textStyle: {
                            color: '#000',
                            fontSize: 12
                        }
                    },
                    lineStyle: {
                        color: '#ccc',
                        type: 'broken'

                    }
                },
                emphasis: {
                    color: '#4883b4',
                    label: {
                        show: true
                    },
                    borderWidth: 4
                }
            },
            data: [
                __data__
            ]
        }";

        $this->data = str_replace('__data__', json_encode($this->data), $template);
    }

}